iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 14
0
Software Development

python 自學系列 第 14

python day14 (File Input、Output)

  • 分享至 

  • xImage
  •  

python 在處理檔案時分為 text file 或 binary file.而處理檔案時會使用 open function.open 參數 mode 可以指定現在處理的是哪種 file 類型.

'r' Read text file (default)
'w' Write text file (如果存在的話會 overwrites)
'x' Write text file (如果檔案已經存在則會丟出 FileExistsError)
'a' Append to text file (會從檔案的結尾開始新增內容)
'rb' Read binary file
'wb' Write binary file (如果存在的話會 overwrites)
'w+b' Open binary file (可讀取跟寫入)
'xb' Write binary file (如果檔案已經存在則會丟出 FileExistsError)
'ab' Append to binary file (會從檔案的結尾開始新增內容)

open function 有很多參數可以使用如下.

open(filename,mode='r',buffering=-1,encoding=None,errors=None,newline=None,closefd=True,opener=None)
newline

newline 為 None 的話,換行符號會根據系統預設(\n\r\n).不希望透過預設的話給參數newline=''即可.可用下列方式查看系統預設換行符號.

>>> import os
>>> os.linesep
'\n'
buffering

buffering 在寫檔案時可以當作一個緩衝區,當達到設定的 buffer 滿時,才會寫入磁碟,可以減少頻繁的對磁碟做 IO.

buffering 為 -1 時,text file 或 binary file 都是系統預設的 io.DEFAULT_BUFFER_SIZE.
buffering 為 0 時,binary file 表示不使用 buffer,text file 不允許設成 0.
buffering 為 1 時,binary file 表示為 1 byte,text file 表示為一行一行緩衝.
buffering 為大於 1 時,就是設定的該大小.

如果 buffering 設 10 個 byte,只輸入 5 個 byte 並不會寫入檔案.

>>> f = open('test_buffered.txt','wb',buffering=10)
>>> f.write(b'hello')
5
> cat test_buffered.txt

再寫一次 buffer 滿了就會 flush 到檔案裡.

>>> f.write(b'hello python')
12
> cat test_buffered.txt
hellohello python
errors

errors 有 strict 和 ignore,如果設 strict 編碼出現問題是會出現錯誤訊息.ignore 是忽略編碼錯誤的訊息.假設有個檔案是 big5.

> file hello.txt
hello.txt: ISO-8859 text

在讀檔時使用 UTF-8 去讀,導致中文有問題,strict 會出現錯誤訊息.

>>> rf = open('hello.txt','r',errors='strict')
>>> rf.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb1 in position 0: invalid start byte

ignore 就不會出現錯誤.

>>> rf = open('hello.txt','r',errors='ignore')
>>> rf.read()
'zn python \n \nHello World'

指定編碼就不會出錯了.

>>> rf = open('hello.txt','r',errors='strict',encoding='big5')
>>> rf.read()
'您好 python \n初學 \nHello World'

write file

真正在使用 open function 時,參數不一定要全給,例如要產生一個檔案並寫入資訊帶兩個參數就可以了,只要給檔名模式即可.

>>> f = open('hello.txt','w')
>>> f.write('您好 python \n')
11
>>> f.write('初學 \n')
4
>>> f.write('Hello World')
11
>>> f.close()

看產生檔案的內容

> cat hello.txt
您好 python
初學
Hello World

用 file 指令查看產生檔案的編碼,是 UTF-8

> file hello.txt
hello.txt: UTF-8 Unicode text

filename 的參數可以指定要產生檔案的路徑,如果沒給路徑的話檔會在執行時的當前目錄產生.

>>> f = open('/Volumes/Transcend/pylearn/hello.txt','w')

可以指定產生檔案的編碼

>>> f = open('hello.txt','w',encoding = 'big5')

可以看到檔案變成不是 UTF-8 了.

> file hello.txt
hello.txt: ISO-8859 text

read file

python 在讀檔時可以選擇一次要讀幾個 bytes 或讀幾行,也可以一次把檔案都讀進來.最簡單的讀檔就是給要讀的檔案跟 r 模式,接著用 read() 可以一次讀取檔案全部的內容.

>>> rf = open('hello.txt','r')
>>> rf.read()
'您好 python \n初學 \nHello World'

但如果檔案非常大,如果機器的 memory 不夠用一次全部讀進來就會出錯.所以可以改成使用 readlines() 方式一行一行讀取進來.使用 strip() 可以刪掉字串前後的空白或換行符號.

>>> rf = open('hello.txt','r')

>>> for line in rf.readlines():
...  print(line.strip())
...
您好 python
初學
Hello World
>>> rf.close()

一次讀取幾個 byte 進來.

>>> f = open('test_buffered.txt','rb')
>>> f.read(5)
b'hello'
>>> f.read(10)
b'hello pyth'
>>> f.close()

with

使用 open function 會回傳一個 file 物件,所以用完時都要把它 close() 掉.如果不 close() 掉,一直開檔案,會造成開啟中的檔案可能會刪不掉,系統能開的檔案數也有限制.使用 with 可以讓程式碼變得簡潔一點不用加 close(),with 區塊的程式碼執行完後,會執行__exit__function,而裡面已經定義好了 close().

def __exit__(self, *args):
    """Context management protocol.  Calls close()"""
    self.close()

原本程式的寫法

>>> f = open('test_buffered.txt','rb')
>>> f.read(5)
b'hello'
>>> f.read(10)
b'hello pyth'
>>> f.close()

改成使用 with

>>> with open('test_buffered.txt','rb') as f:
...  f.read(5)
...  f.read(10)
...
b'hello'
b'hello pyth'

可以看到沒有寫 close(),使用 closed 檢查是否關閉,True 代表已經被關閉.

>>> f.closed
True

上一篇
python day13 (sequence functions)
下一篇
python day15 (classes)
系列文
python 自學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言